home *** CD-ROM | disk | FTP | other *** search
/ Complete Linux / Complete Linux.iso / docs / apps / sound / players / maplay_t.z / maplay_t / obuffer.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-02-21  |  6.8 KB  |  302 lines

  1. /*
  2.  *  @(#) obuffer.c 1.6, last edit: 2/21/94 18:10:13
  3.  *  @(#) Copyright (C) 1993, 1994 Tobias Bading (bading@cs.tu-berlin.de)
  4.  *  @(#) Berlin University of Technology
  5.  *
  6.  *  This program is free software; you can redistribute it and/or modify
  7.  *  it under the terms of the GNU General Public License as published by
  8.  *  the Free Software Foundation; either version 2 of the License, or
  9.  *  (at your option) any later version.
  10.  *
  11.  *  This program is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14.  *  GNU General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU General Public License
  17.  *  along with this program; if not, write to the Free Software
  18.  *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  */
  20.  
  21. #include <stdio.h>
  22. #include <stdlib.h>
  23. #include <iostream.h>
  24. #include <errno.h>
  25. #include <unistd.h>
  26. #include <fcntl.h>
  27. #include <sys/ioctl.h>
  28. #include "obuffer.h"
  29. #include "header.h"
  30.  
  31.  
  32. extern "C" int ioctl (int, int ...);
  33.  
  34.  
  35. ShortObuffer::ShortObuffer (uint32 number_of_channels)
  36. {
  37. #ifdef DEBUG
  38.   if (!number_of_channels || number_of_channels > MAXCHANNELS)
  39.   {
  40.     cerr << "ShortObuffer: number of channels has to be in [1, " <<  MAXCHANNELS << "] !\n";
  41.     exit (1);
  42.   }
  43. #endif
  44.   channels = number_of_channels;
  45.   for (int i = 0; i < number_of_channels; ++i)
  46.     bufferp[i] = buffer + i;
  47. }
  48.  
  49.  
  50. void ShortObuffer::append (uint32 channel, int16 value)
  51. {
  52. #ifdef DEBUG
  53.   if (channel >= channels)
  54.   {
  55.     cerr << "illegal channelnumber in ShortObuffer::append()!\n";
  56.     exit (1);
  57.   }
  58.   if (bufferp[channel] - buffer >= OBUFFERSIZE)
  59.   {
  60.     cerr << "ShortObuffer: buffer overflow!\n";
  61.     exit (1);
  62.   }
  63. #endif
  64.   *bufferp[channel] = value;
  65.   bufferp[channel] += channels;
  66. }
  67.  
  68.  
  69. void ShortObuffer::write_buffer (int fd)
  70. {
  71.   int length = (int)((char *)bufferp[0] - (char *)buffer);
  72.   if (write (fd, buffer, length) != length)
  73.     cerr << "Warning: couldn't write all samples\n";
  74.   for (int i = 0; i < channels; ++i)
  75.     bufferp[i] = buffer + i;
  76. }
  77.  
  78.  
  79.  
  80. #ifdef Indigo
  81. IndigoObuffer::IndigoObuffer (uint32 number_of_channels, Header *header)
  82. {
  83. #ifdef DEBUG
  84.   if (!number_of_channels || number_of_channels > MAXCHANNELS)
  85.   {
  86.     cerr << "IndigoObuffer: number of channels has to be in [1, " <<  MAXCHANNELS << "] !\n";
  87.     exit (1);
  88.   }
  89. #endif
  90.   channels = number_of_channels;
  91.   for (int i = 0; i < number_of_channels; ++i)
  92.     bufferp[i] = buffer + i;
  93.  
  94.   // open an audio port and configure it:
  95.   ALconfig config;
  96.   if (!(config = ALnewconfig ()))
  97.   {
  98.     cerr << "ALnewconfig failed!\n";
  99.     exit (1);
  100.   }
  101.   ALsetwidth (config, AL_SAMPLE_16);
  102.   if (channels == 1)
  103.     ALsetchannels (config, AL_MONO);
  104.   else
  105.     ALsetchannels (config, AL_STEREO);
  106.   if (!(port = ALopenport ("MPEG audio player", "w", config)))
  107.   {
  108.     cerr << "can't allocate an audio port!\n";
  109.     exit (1);
  110.   }
  111.  
  112.   // set sample rate:
  113.   long pvbuffer[2] = { AL_OUTPUT_RATE, 0 };
  114.   pvbuffer[1] = header->frequency ();
  115.   ALsetparams (AL_DEFAULT_DEVICE, pvbuffer, 2);
  116.   ALfreeconfig (config);
  117. }
  118.  
  119.  
  120. IndigoObuffer::~IndigoObuffer (void)
  121. {
  122.   while (ALgetfilled (port) > 0)
  123.     sleep (1);
  124.   ALcloseport (port);
  125. }
  126.  
  127.  
  128. void IndigoObuffer::append (uint32 channel, int16 value)
  129. {
  130. #ifdef DEBUG
  131.   if (channel >= channels)
  132.   {
  133.     cerr << "illegal channelnumber in IndigoObuffer::append()!\n";
  134.     exit (1);
  135.   }
  136.   if (bufferp[channel] - buffer >= OBUFFERSIZE)
  137.   {
  138.     cerr << "IndigoObuffer: buffer overflow!\n";
  139.     exit (1);
  140.   }
  141. #endif
  142.   *bufferp[channel] = value;
  143.   bufferp[channel] += channels;
  144. }
  145.  
  146.  
  147. void IndigoObuffer::write_buffer (int)
  148. {
  149.   ALwritesamps (port, buffer, (long)(bufferp[0] - buffer));
  150.   for (int i = 0; i < channels; ++i)
  151.     bufferp[i] = buffer + i;
  152. }
  153. #endif // Indigo
  154.  
  155.  
  156. #ifdef SPARC
  157. int SparcObuffer::audio_fd = -1;
  158.  
  159. SparcObuffer::SparcObuffer (uint32 number_of_channels, Header *header,
  160.                 bool use_speaker, bool use_headphone, bool use_line_out)
  161. {
  162. #ifdef DEBUG
  163.   if (!number_of_channels || number_of_channels > MAXCHANNELS)
  164.   {
  165.     cerr << "SparcObuffer: 0 < number of channels < " << MAXCHANNELS << "!\n";
  166.     exit (1);
  167.   }
  168. #endif
  169.   channels = number_of_channels;
  170.   for (int i = 0; i < number_of_channels; ++i)
  171.     bufferp[i] = buffer + i;
  172.  
  173.   if (audio_fd < 0)
  174.   {
  175.     cerr << "Internal error, SparcObuffer::audio_fd has to be initialized\n"
  176.         "by SparcObuffer::class_suitable()!\n";
  177.     exit (1);
  178.   }
  179.  
  180.   // configure the device:
  181.   audio_info info;
  182.   AUDIO_INITINFO (&info);
  183.   info.output_muted = False;
  184.   info.play.encoding = AUDIO_ENCODING_LINEAR;
  185.   info.play.precision = 16;
  186.   info.play.channels = channels;
  187.   info.play.sample_rate = header->frequency ();
  188.   if (use_speaker)
  189.     info.play.port |= AUDIO_SPEAKER;
  190.   if (use_headphone)
  191.     info.play.port |= AUDIO_HEADPHONE;
  192.   if (use_line_out)
  193.     info.play.port |= AUDIO_LINE_OUT;
  194.   info.play.balance = AUDIO_MID_BALANCE;
  195.   if (ioctl (audio_fd, AUDIO_SETINFO, &info))
  196.   {
  197.     perror ("configuration of /dev/audio failed");
  198.     exit (1);
  199.   }
  200. }
  201.  
  202.  
  203. SparcObuffer::~SparcObuffer (void)
  204. {
  205.   sleep (1);
  206.   close (audio_fd);
  207. }
  208.  
  209.  
  210. void SparcObuffer::append (uint32 channel, int16 value)
  211. {
  212. #ifdef DEBUG
  213.   if (channel >= channels)
  214.   {
  215.     cerr << "illegal channelnumber in SparcObuffer::append()!\n";
  216.     exit (1);
  217.   }
  218.   if (bufferp[channel] - buffer >= OBUFFERSIZE)
  219.   {
  220.     cerr << "buffer overflow!\n";
  221.     exit (1);
  222.   }
  223. #endif
  224.   *bufferp[channel] = value;
  225.   bufferp[channel] += channels;
  226. }
  227.  
  228.  
  229. void SparcObuffer::write_buffer (int)
  230. {
  231.   int length = (int)((char *)bufferp[0] - (char *)buffer);
  232.   if (write (audio_fd, buffer, length) != length)
  233.     cerr << "Warning: couldn't write all samples to /dev/audio\n";
  234.   for (int i = 0; i < channels; ++i)
  235.     bufferp[i] = buffer + i;
  236. }
  237.  
  238.  
  239. int SparcObuffer::open_audio_device (void)
  240. {
  241.   int fd;
  242.  
  243.   if ((fd = open ("/dev/audio", O_WRONLY | O_NDELAY)) < 0)
  244.     if (errno == EBUSY)
  245.     {
  246.       cerr << "Sorry, the audio device is busy!\n";
  247.       exit (1);
  248.     }
  249.     else
  250.     {
  251.       perror ("can't open /dev/audio for writing");
  252.       exit (1);
  253.     }
  254.   return fd;
  255. }
  256.  
  257.  
  258. #ifdef Solaris
  259. void SparcObuffer::get_device_type (int fd, audio_device *devtype)
  260. {
  261.   if (ioctl (fd, AUDIO_GETDEV, devtype))
  262.   {
  263.     perror ("ioctl on /dev/audio");
  264.     exit (1);
  265.   }
  266. }
  267. #else
  268. int SparcObuffer::get_device_type (int fd)
  269. {
  270. #ifdef AUDIO_GETDEV
  271.   int devtype;
  272.   if (ioctl (fd, AUDIO_GETDEV, &devtype))
  273.   {
  274.     perror ("ioctl on /dev/audio");
  275.     exit (1);
  276.   }
  277.   return devtype;
  278. #else
  279.   cerr << "Warning: AUDIO_GETDEV ioctl not available!\n";
  280.   return -1;
  281. #endif
  282. }
  283. #endif // !Solaris
  284.  
  285.  
  286. bool SparcObuffer::class_suitable (void)
  287. {
  288.   // check for the dbri audio device:
  289.   audio_fd = open_audio_device ();
  290. #ifdef Solaris
  291.   audio_device devtype;
  292.   get_device_type (audio_fd, &devtype);
  293.   if (!strcmp (devtype.name, "SUNW,dbri"))
  294. #else
  295.   if (get_device_type (audio_fd) == AUDIO_DEV_SPEAKERBOX)
  296. #endif
  297.     return True;
  298.   else
  299.     return False;
  300. }
  301. #endif
  302.